package com.sy.simpleegg.platform.kkb.signUtil

import com.sy.simpleegg.ext.logFile
import com.sy.simpleegg.util.ByteUtil
import com.ych.ytdevicesdk.utils.LogUtilsX
import java.math.BigInteger
import java.security.InvalidKeyException
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.Locale
import java.util.TreeMap
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec


object SignUtil {
    /**
     * 使用 HMAC-SHA1 签名方法对data进行签名
     *
     * @param data 被签名的字符串
     * @param key  密钥
     * @return 加密后的字符串
     */
    private val HMAC_SHA1_ALGORITHM = "HmacSHA1"
    val KEY = "C5D7C9FD354349B1A23D1DEE318D4E58"

    fun genHMAC(data: String, key: String): String? {
        var result: String? = null
        try {
            //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
            val signinKey = SecretKeySpec(key.toByteArray(), HMAC_SHA1_ALGORITHM)
            //生成一个指定 Mac 算法 的 Mac 对象
            val mac = Mac.getInstance(HMAC_SHA1_ALGORITHM)
            //用给定密钥初始化 Mac 对象
            mac.init(signinKey)
            //完成 Mac 操作
            val rawHmac = mac.doFinal(data.toByteArray())
            result = ByteUtil.bytes2HexStr(rawHmac).uppercase()
//            result = StringUtils.bytes2HexString(rawHmac).toUpperCase()
        } catch (e: NoSuchAlgorithmException) {
            System.err.println(e.message)
        } catch (e: InvalidKeyException) {
            System.err.println(e.message)
        }
        return result
    }

    fun getSige(
        map: Map<String, Any?>,
        key: String,
    ): String? {
        val headerMapTyep: MutableMap<String, Any?> =
            TreeMap()
        val sige = StringBuffer()
        for (s in map.keys) {
            headerMapTyep[s.lowercase(Locale.getDefault())] = map[s]
        }
        LogUtilsX.d("okhttp:  $map")
        val iterator: Iterator<Map.Entry<String, Any?>> =
            headerMapTyep.entries.iterator()
        while (iterator.hasNext()) {
            val (key1, value) = iterator.next()
            sige.append(key1.lowercase(Locale.getDefault())).append("=")
                .append(value)
            if (iterator.hasNext()) {
                sige.append("&")
            }
        }
        return genHMAC(sige.toString(), key)
    }

    fun getSige(
        map: MutableMap<String, Any?>,
        secret: String,
        isAddCommon: Boolean = true
    ): String {

        val tempList: MutableList<Pair<String, Any>> = mutableListOf()
        map.toList().forEach { item ->
            item.second?.let {
                tempList.add(Pair(item.first, item.second!!))
            }
        }

        val originalStr = StringBuilder()
        tempList.sortedBy { it.first }.forEach { sortedItem ->
            if (originalStr.isEmpty()){
                originalStr
                    .append(sortedItem.first)
                    .append("=")
                    .append(sortedItem.second)
            }else{
                originalStr.append("&")
                    .append(sortedItem.first)
                    .append("=")
                    .append(sortedItem.second)
            }
        }

        originalStr.append("&")
            .append(secret)
        logFile("MD5加密原始数据：${originalStr}")
        return md5(originalStr.toString())
    }

    fun md5(encodeStr: String): String{
        val md5s = MessageDigest.getInstance("MD5").digest(encodeStr.toByteArray())
        // 直接以 BASE64 暴力解析成可读字符串
//        val s1 = Base64.getEncoder().encodeToString(md5s)
        // 存储到 BigInteger 中，并以 16 进制的格式输出（推荐）
        return BigInteger(1, md5s).toString(16).let { md5Str ->
            if (md5Str.length == 32){
                md5Str
            }else if (md5Str.length < 32){
                var result = ""
                for (i in 0 until 32 - md5Str.length){
                    result = "0$result"
                }
                "$result$md5Str"
            }else{
                md5Str.substring(0, 32)
            }
        }
    }
}